import { ExecutionContext, ForbiddenException, Inject, Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { Reflector } from '@nestjs/core';
import { UserService } from '@/modules/system/user/user.service';
import { NOT_TOKEN } from '@/decorators/not-token.decorator';
import { PathMatcher } from '@/common/utils/path-matcher.util';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
    constructor(
        private readonly reflector: Reflector,
        @Inject(UserService)
        private readonly userService: UserService,
    ) {
        super();
    }

    async canActivate(ctx: ExecutionContext): Promise<boolean> {
        const request = ctx.switchToHttp().getRequest();
        const currentPath = request.url;
        // 直接调用工具类，指定组件类型为 guard
        if (PathMatcher.isExcluded(currentPath, 'guard', [])) return true;
        // 函数，类 是否允许 无 token 访问
        const notToken = this.reflector.getAllAndOverride<boolean>(NOT_TOKEN, [ctx.getHandler(), ctx.getClass()]);
        console.log('notToken', notToken);
        if (notToken) return true;
        // const res = ctx.switchToHttp().getResponse()
        const accessToken = request.headers.authorization;
        // console.log("accessToken",accessToken)
        if (!accessToken) throw new ForbiddenException('请先登录');
        const atUserId = this.userService.verifyToken(accessToken); // 自定义 token 校验
        // console.log("atUserId",atUserId)
        if (!atUserId) throw new UnauthorizedException('当前登录已过期，请重新登录');
        return this.activate(ctx);
    }

    async activate(ctx: ExecutionContext): Promise<boolean> {
        return super.canActivate(ctx) as Promise<boolean>;
    }
}
